using System;
using System.Windows.Documents;
using System.Windows.Media;
using com.bodurov.SilverlightControls.XmlCodeEditor.Enums;

namespace com.bodurov.SilverlightControls.XmlCodeEditor
{
    public class Token
    {
        public Run Run { get; set; }
        public XmlElement Type { get; set; }
        public XmlArea Within { get; set; }
        public virtual string Content { get; set; }

        public string ContentAndType { get { return String.Format("{0}:{1}", Type, Content); } }


        public static Color ColorByType(XmlElement type)
        {
            switch (type)
            {
                case XmlElement.OpeningTagName:
                case XmlElement.ClosingTagName:
                    return Colors.Brown;
                case XmlElement.OpeningTagNamespace:// <asp: without <
                case XmlElement.ClosingTagNamespace:// </asp: without </
                    return Color.FromArgb(0xFF, 0x00, 0x77, 0x99);
                case XmlElement.AttributeName:
                case XmlElement.Entity: // &nbsp;
                    return Colors.Red;
                case XmlElement.AttributeSingleQuoteString:
                case XmlElement.AttributeDualQuoteString:
                case XmlElement.AttributeLiteralContent:
                    return Colors.Blue;
                case XmlElement.OpeningServerScriptBracket:// <%
                case XmlElement.ServerBlockSpecialChar:// @, = or #
                case XmlElement.ClosingServerScriptBracket: // %>
                    return Color.FromArgb(0xFF, 0xDD, 0x11, 0xAA);
                case XmlElement.AttributeEqualSign:
                    return Color.FromArgb(0xFF, 0x00, 0x99, 0x00);
                case XmlElement.Keyword:
                    return Color.FromArgb(0xFF, 0x00, 0xBB, 0xBB);
                case XmlElement.OpeningTagBeginBracket:
                case XmlElement.OpeningTagEndBracket:
                case XmlElement.OpeningTagClosingBracket:
                case XmlElement.ClosingTagBeginBracket:
                case XmlElement.ClosingTagEndBracket:
                case XmlElement.OpeningProcessingInstructionBracket: // <?
                case XmlElement.ClosingProcessingInstructionBracket: // ?>
                    return Colors.Blue;
                case XmlElement.OpeningClientSideCommentBracket: // <!--
                case XmlElement.ClosingClientSideCommentBracket: // -->
                case XmlElement.InsideClientSideComment:
                    return Colors.DarkGray;
                case XmlElement.OutsideTagContent:
                case XmlElement.WhiteSpace:
                    return Colors.Black;
                case XmlElement.InsideServerScript:
                    return Color.FromArgb(0xFF, 0x33, 0x66, 0x99);
                default:
                    return Colors.Black;
            }
        }


        public Run ToRun()
        {
            var run =  new Run
            {
                Foreground = new SolidColorBrush(ColorByType(this.Type)),
                Text = this.Content
            };
            this.Run = run;
            return run;
        }

        public bool IsTagEndElement
        {
            get
            {
                switch (this.Type)
                {
                    case XmlElement.OpeningTagEndBracket:
                    case XmlElement.ClosingTagEndBracket:
                    case XmlElement.OpeningTagClosingBracket:
                    case XmlElement.ClosingProcessingInstructionBracket:
                    case XmlElement.ClosingClientSideCommentBracket:
                    case XmlElement.ClosingServerScriptBracket:
                        return true;
                    default:
                        return false;
                }
            }
        }

        public XmlArea NextArea
        {
            get { return IsTagEndElement ? XmlArea.OutsideTag : this.Within; }
        }
    }
}